﻿using System;
using UnityEngine;

namespace SillyCube
{
    public enum DragState
    {
        None,
        InDrag,
    }
    
    public class GameManager : MonoBehaviour
    {
        private static GameManager _instance;
        public static GameManager Instance => _instance;
        [SerializeField] private LevelManager levelManager;
        public LevelManager LevelManager => levelManager;
        
        [SerializeField] private CubeContainer cubeContainer;
        public CubeContainer CubeContainer => cubeContainer;

        [SerializeField] private GameObject debugObjectPrefab;
        [SerializeField] private HintLineController hintLineRenderer;
        
        private Vector2 forceVector;
        
        [SerializeField] private float gameTimeScale = 1f;

        private bool dragFromCube = false;

        private void Start()
        {
            hintLineRenderer.gameObject.SetActive(false);
            GameInit();

            Application.targetFrameRate = 120;
        }

        private void OnEnable()
        {
            _instance = this;
        }

        private void Update()
        {
            Time.timeScale = gameTimeScale;

            if (Input.GetKeyDown(KeyCode.R))
            {
                GameInit();
            }
        }

        public void OnTouchStateChanged(Vector2 worldPoint2D, bool state)
        {
            var ctrl = Instance.CubeContainer.CurrentCubeController;
            
            if (!state && dragFromCube)
            {
                dragFromCube = false;
                
                if (ctrl is not null && forceVector.magnitude > 0.45f)
                {
                    ctrl.Jump(forceVector);
                }
                
                hintLineRenderer.gameObject.SetActive(false);
            }
            else if (state && ctrl.AllowDragForce())
            {
                var cubePos = (Vector2) ctrl.transform.position;

                if ((cubePos - worldPoint2D).magnitude < 0.8f)
                {
                    dragFromCube = true;
                
                    hintLineRenderer.gameObject.SetActive(true);
                }
            }
        }

        public void OnDrag(Vector2 worldPos2D)
        {
            if (!dragFromCube)
            {
                return;
            }
            
            var cube = GameManager.Instance.CubeContainer.CurrentCubeController;

            var cubePos = cube.transform.position;
            Vector2 cubePos2D = cubePos;
            
            forceVector = cubePos2D - worldPos2D;
            forceVector = Mathf.Min(forceVector.magnitude, cube.GetMaxForceMagnitude()) * forceVector.normalized;

            var force3D = new Vector3(forceVector.x, forceVector.y, 0);

            hintLineRenderer.SetColor(Color.Lerp(Color.white, Color.red, forceVector.magnitude / 2.5f));
            
            hintLineRenderer.LineRenderer.positionCount = 2;
            hintLineRenderer.LineRenderer.SetPosition(0, cubePos);
            hintLineRenderer.LineRenderer.SetPosition(1, cubePos - force3D);
        }

        public void GameInit()
        {
            var level = GameManager.Instance.levelManager.LoadLevel(0);
            if (level)
                level.OnSpawnCube();
        }
    }
}